"""Base class for handling markdown document body"""

import re
from pathlib import Path
from typing import List

from mdtool.error_handler import (
    FileSystemError,
)
from mdtool.image.reference import ImageReference


class BaseBody:
    """Base class for handling markdown document body text"""

    def __init__(self, body_text: str, source_dir: str):
        """Initialize BaseBody

        Args:
            body_text: The body text content of the markdown document
            source_dir: Absolute path to the source directory containing the markdown file

        Raises:
            FileSystemError: If source_dir is invalid
        """
        self.body_text = body_text
        # 验证 source_dir
        if not source_dir:
            raise FileSystemError("Source directory is required")
        source_path = Path(source_dir)
        if not source_path.is_absolute():
            raise FileSystemError(f"Source directory {source_dir} must be absolute")
        if not source_path.exists():
            raise FileSystemError(f"Source directory {source_dir} does not exist")
        if not source_path.is_dir():
            raise FileSystemError(f"Source directory {source_dir} is not a directory")

        self._source_dir = source_dir
        self._image_refs: List[ImageReference] = []
        self._image_refs_cached: bool = False

    def get_image_references(self) -> List[ImageReference]:
        if self._image_refs_cached:
            return self._image_refs
        # Find all image references in content
        self._image_refs = []
        img_links = re.findall(r"!\[(.*?)\]\((.*?)\)", self.body_text)
        for alt_text, link in img_links:
            imgRef = ImageReference(
                url_in_text=link,
                original_path=link,
                target_path="",
                existed=False,
                external=False,
                alt_text=alt_text,
            )
            imgRef.external = link.startswith("http")
            if imgRef.external:
                # TODO: check if the external image exists on the web
                imgRef.existed = True
            else:
                imgRef.original_path = str(Path(self._source_dir) / link.lstrip("./"))
                imgRef.existed = Path(imgRef.original_path).exists()

            self._image_refs.append(imgRef)
        self._image_refs_cached = True
        return self._image_refs

    def to_string(self) -> str:
        """Convert body back to string format

        Returns:
            Body content as string
        """
        return self.body_text.rstrip() + "\n"

    def check_format(self) -> list[str]:
        """Check the format of the body"""
        result = []
        for img_ref in self.get_image_references():
            if not img_ref.check():
                result.append(img_ref.original_path)
        return result
